/*******************************************************************************
*
*	:  IO
*
*******************************************************************************/
#define PORT_PIN_CTEAT
#include "bsp.h"
#include "bsp_io.h"
#include "iohandle.h"
#include "pincfg.h"
#include "mytype.h"


/*******************************************************************************
* @brief  gpio cfg list
*******************************************************************************/
static gpio_init_cfg_type gpio_cfg[] = {
	{GPIOA, GPIO_MODE_AF_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF5_USART1, 1, GPIO_PIN_9},
	{GPIOA, GPIO_MODE_AF_PP, GPIO_PULL_UP, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF5_USART1, 1, GPIO_PIN_10},
	
	{GPIOB, GPIO_MODE_AF_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF7_UART3, 1, GPIO_PIN_8},
	{GPIOB, GPIO_MODE_AF_PP, GPIO_PULL_UP, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF7_UART3, 1, GPIO_PIN_9},
	
	{GPIOB, GPIO_MODE_AF_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF7_UART4, 1, GPIO_PIN_14},
	{GPIOB, GPIO_MODE_AF_PP, GPIO_PULL_UP, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF7_UART4, 1, GPIO_PIN_15},
	
	{GPIOA, GPIO_MODE_OUT_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, 0, 1, GPIO_PIN_15},
	
	{GPIOB, GPIO_MODE_AF_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF2_SPI1, 1, GPIO_PIN_3},//SCK
	{GPIOB, GPIO_MODE_AF_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF2_SPI1, 1, GPIO_PIN_4},//MISO
	{GPIOB, GPIO_MODE_AF_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF1_SPI1, 1, GPIO_PIN_5},//MOSI
};

/*******************************************************************************
* @brief  bsp_gpio_init
* \param[in] us delay
* \retval: none
*******************************************************************************/
void bsp_gpio_init(void)
{
	int index;

	// clock enable
	RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);
	
	RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
	RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
	RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOC);
	RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOD);
	
	
	for(int index = 0;index < sizeof(gpio_cfg)/sizeof(gpio_cfg[0]);index++)
	{
		GPIO_InitType GPIO_InitStructure;

		GPIO_Structure_Initialize(&GPIO_InitStructure);
		
		GPIO_InitStructure.Pin          = gpio_cfg[index].pin;

		GPIO_InitStructure.GPIO_Mode    = gpio_cfg[index].mode;

		GPIO_InitStructure.GPIO_Current = gpio_cfg[index].current;
		
		GPIO_InitStructure.GPIO_Alternate = gpio_cfg[index].alt;
		
		GPIO_InitStructure.GPIO_Slew_Rate = gpio_cfg[index].rate;
		
		GPIO_InitStructure.GPIO_Pull = gpio_cfg[index].pull;

		GPIO_Peripheral_Initialize(gpio_cfg[index].port, &GPIO_InitStructure);
		
		if(GPIO_InitStructure.GPIO_Mode == GPIO_MODE_OUT_PP || GPIO_InitStructure.GPIO_Mode == GPIO_MODE_OUT_OD)
		{
			if(gpio_cfg[index].val_init)
				GPIO_Pins_Set(gpio_cfg[index].port, gpio_cfg[index].pin);
			else
				GPIO_Pins_Reset(gpio_cfg[index].port, gpio_cfg[index].pin);
		}
	}
	
	o_led1.mode(PIN_MODE_OUT_PP);
	o_led2.mode(PIN_MODE_OUT_PP);
	//o_led3.mode(PIN_MODE_OUT_PP);
	
	key1.dir_in_up();
	key2.dir_in_up();
	key3.dir_in_up();
	key4.dir_in_up();
	
	oled_cs.dir_out_pp();
	oled_rst.dir_out_pp();
	//oled_dc.dir_out_pp();
	oled_cs.en();
	oled_rst.dis();
	//oled_dc.en();
}

#define pin_mode_din()	group_bits2_set(port->PMODE, pin, 0)
#define pin_mode_out()	group_bits2_set(port->PMODE, pin, 1)
#define pin_mode_alt()	group_bits2_set(port->PMODE, pin, 2)
#define pin_mode_ain()	group_bits2_set(port->PMODE, pin, 3)

#define pin_otype_pp()	group_bits1_set(port->POTYPE, pin, 0)
#define pin_otype_od()	group_bits1_set(port->POTYPE, pin, 1)

#define pin_ospd_high()	group_bits1_set(port->SR, pin, 0)
#define pin_ospd_low()	group_bits1_set(port->SR, pin, 1)

#define pin_pull_none()	group_bits2_set(port->PUPD, pin, 0)
#define pin_pull_up()	group_bits2_set(port->PUPD, pin, 1)
#define pin_pull_down()	group_bits2_set(port->PUPD, pin, 2)

#define pin_odrv_2mA()	group_bits2_set(port->DS, pin, 0)
#define pin_odrv_8mA()	group_bits2_set(port->DS, pin, 1)
#define pin_odrv_4mA()	group_bits2_set(port->DS, pin, 2)
#define pin_odrv_12mA()	group_bits2_set(port->DS, pin, 3)

/*******************************************************************************
* @brief  bsp_gpio
* \param[in] us delay
* \retval: none
*******************************************************************************/
void bsp_gpio_mode_out_pp(GPIO_Module *port, uint8_t pin)
{
	GPIO_InitType GPIO_InitStruct;	
	intx_alloc();

	intx_disable();

	pin_mode_out();
	pin_otype_pp();
	pin_ospd_high();
	pin_pull_none();
	pin_odrv_8mA();
	
	intx_enable();
}

void bsp_gpio_mode_out_od(GPIO_Module *port, uint8_t pin)
{
	GPIO_InitType GPIO_InitStruct;	
	intx_alloc();

	intx_disable();

	pin_mode_out();
	pin_otype_od();
	pin_ospd_high();
	pin_pull_none();
	pin_odrv_8mA();
	
	intx_enable();
}

void bsp_gpio_mode_out_pp_spd(GPIO_Module *port, uint8_t pin, uint32_t spd)
{
	GPIO_InitType GPIO_InitStruct;	
	intx_alloc();

	intx_disable();

	pin_mode_out();
	pin_otype_pp();
	pin_ospd_high();
	pin_pull_none();
	pin_odrv_8mA();
	
	intx_enable();
}

void bsp_gpio_mode_out_od_spd(GPIO_Module *port, uint8_t pin, uint32_t spd)
{
	GPIO_InitType GPIO_InitStruct;	
	intx_alloc();

	intx_disable();

	pin_mode_out();
	pin_otype_pp();
	pin_ospd_high();
	pin_pull_none();
	pin_odrv_8mA();
	
	intx_enable();
}

void bsp_gpio_mode_in_up(GPIO_Module *port, uint8_t pin)
{
	GPIO_InitType GPIO_InitStruct;	
	intx_alloc();

	intx_disable();

	pin_mode_din();
	pin_otype_pp();
	pin_ospd_high();
	pin_pull_up();
	pin_odrv_2mA();
	
	intx_enable();
}

void bsp_gpio_mode_in_dn(GPIO_Module *port, uint8_t pin)
{
	GPIO_InitType GPIO_InitStruct;	
	intx_alloc();

	intx_disable();

	pin_mode_din();
	pin_otype_pp();
	pin_ospd_high();
	pin_pull_down();
	pin_odrv_2mA();
	
	intx_enable();
}

void bsp_gpio_mode_in_ft(GPIO_Module *port, uint8_t pin)
{
	GPIO_InitType GPIO_InitStruct;	
	intx_alloc();

	intx_disable();

	pin_mode_din();
	pin_otype_pp();
	pin_ospd_high();
	pin_pull_none();
	pin_odrv_2mA();
	
	intx_enable();
}

void bsp_gpio_mode_ain(GPIO_Module *port, uint8_t pin)
{
	GPIO_InitType GPIO_InitStruct;	
	intx_alloc();

	intx_disable();

	pin_mode_ain();
	pin_otype_pp();
	pin_ospd_high();
	pin_pull_none();
	pin_odrv_2mA();
	
	intx_enable();
}

void bsp_gpio_mode_set(GPIO_Module *port, uint8_t pin, char pm)
{
	switch (pm)
	{
	case PIN_MODE_IN_UP:
	{
		bsp_gpio_mode_in_up(port, pin);
		break;
	}
	case PIN_MODE_IN_DN:
	{
		bsp_gpio_mode_in_dn(port, pin);
		break;
	}
	case PIN_MODE_IN_FLOAT:
	{
		bsp_gpio_mode_in_ft(port, pin);
		break;
	}
	case PIN_MODE_IN_AIN:
	{
		bsp_gpio_mode_ain(port, pin);
		break;
	};
	case PIN_MODE_OUT_SL_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 2);
		break;
	}
	case PIN_MODE_OUT_SL_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 2);
		break;
	}
	case PIN_MODE_OUT_SM_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 2);
		break;
	}
	case PIN_MODE_OUT_SM_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 2);
		break;
	}
	case PIN_MODE_OUT_SH_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 1);
		break;
	}
	case PIN_MODE_OUT_SH_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 1);
		break;
	}
	default:
	{
		break;
	}
	}
}